﻿using System;
using System.IO;
using Microsoft.Build.BuildEngine;
using Microsoft.WowAddonStudio.Project.Import;
using Microsoft.WowAddonStudio.Project.Import.Ace;
using Microsoft.WowAddonStudio.Project.Import.Folder;
using NUnit.Framework;

namespace WowProjectPackage.Tests.Import
{
	/// <summary>
	/// This class implements test cases for project builder.
	/// </summary>
	[TestFixture]
	public class ProjectBuilderTest : ImporterBaseTest
	{
		#region Setup/Teardown

		[SetUp]
		public override void SetUp()
		{
			base.SetUp();
			importer = new FolderImportPlugin();
			aceImporter = new AceImportPlugin();
			builder = new ProjectBuilder();
			testDataPath = Path.Combine(
				Environment.CurrentDirectory,
				@"Import\TestData");
		}

		[TearDown]
		public override void TearDown()
		{
			base.TearDown();
		}

		#endregion

		protected FolderImportPlugin importer;
		protected AceImportPlugin aceImporter;
		protected ProjectBuilder builder;
		protected string testDataPath;

		[Test]
		public void TestAbakusAddonBuild()
		{
			Project project = builder.Build(targetUri.LocalPath,
			                                aceImporter.Import(new AceImportSettings(abakusUri)));
			Assert.AreEqual(Directory.GetFiles(targetUri.LocalPath).Length, 4);

			using (StreamReader sr = File.OpenText(Path.Combine(testDataPath, "AbakusResult.xml")))
			{
				string expectedXml = sr.ReadToEnd();
				Assert.AreEqual(expectedXml, project.Xml);
			}
		}

		[Test]
		public void TestAce3AddonBuild()
		{
			Project project = builder.Build(targetUri.LocalPath,
			                                aceImporter.Import(new AceImportSettings(ace3Uri)));
			Assert.AreEqual(Directory.GetFiles(targetUri.LocalPath).Length, 8);

			using (StreamReader sr = File.OpenText(Path.Combine(testDataPath, "Ace3Result.xml")))
			{
				string expectedXml = sr.ReadToEnd();
				Assert.AreEqual(expectedXml, project.Xml);
			}
		}

		[Test]
		public void TestChinchillaAddonBuild()
		{
			Project project = builder.Build(targetUri.LocalPath,
			                                aceImporter.Import(new AceImportSettings(chinchillaUri)));
			Assert.AreEqual(Directory.GetFiles(targetUri.LocalPath).Length, 7);

			using (StreamReader sr = File.OpenText(Path.Combine(testDataPath, "ChincillaResult.xml")))
			{
				string expectedXml = sr.ReadToEnd();
				Assert.AreEqual(expectedXml, project.Xml);
			}
		}

		[Test]
		public void TestDeadlyBossModsDBMApiBuild()
		{
			var deadlyBossSrc = new Uri(Path.Combine(deadlyBossUri.LocalPath, "DBM_API"));

			Project project = builder.Build(targetUri.LocalPath,
			                                importer.Import(new FolderImportSettings(deadlyBossSrc)));
			Assert.AreEqual(Directory.GetFiles(targetUri.LocalPath).Length, 15);

			using (StreamReader sr = File.OpenText(Path.Combine(testDataPath, "DBMApiResult.xml")))
			{
				string expectedXml = sr.ReadToEnd();
				Assert.AreEqual(expectedXml, project.Xml);
			}
		}

		[Test]
		public void TestDeadlyBossModsDBMBattlegroundsBuild()
		{
			var deadlyBossSrc = new Uri(Path.Combine(deadlyBossUri.LocalPath, "DBM_Battlegrounds"));
			Project project = builder.Build(targetUri.LocalPath,
			                                importer.Import(new FolderImportSettings(deadlyBossSrc)));
			Assert.AreEqual(Directory.GetFiles(targetUri.LocalPath).Length, 13);

			using (StreamReader sr = File.OpenText(Path.Combine(testDataPath, "DBMBattlegroundsResult.xml")))
			{
				string expectedXml = sr.ReadToEnd();
				Assert.AreEqual(expectedXml, project.Xml);
			}
		}

		[Test]
		public void TestDeadlyBossModsDBMBlackTempleBuild()
		{
			var deadlyBossSrc = new Uri(Path.Combine(deadlyBossUri.LocalPath, "DBM_BlackTemple"));
			Project project = builder.Build(targetUri.LocalPath,
			                                importer.Import(new FolderImportSettings(deadlyBossSrc)));
			Assert.AreEqual(Directory.GetFiles(targetUri.LocalPath).Length, 15);

			using (StreamReader sr = File.OpenText(Path.Combine(testDataPath, "DBMBlackTempleResult.xml")))
			{
				string expectedXml = sr.ReadToEnd();
				Assert.AreEqual(expectedXml, project.Xml);
			}
		}

		[Test]
		public void TestDeadlyBossModsDBMGUIBuild()
		{
			var deadlyBossSrc = new Uri(Path.Combine(deadlyBossUri.LocalPath, "DBM_GUI"));
			Project project = builder.Build(targetUri.LocalPath,
			                                importer.Import(new FolderImportSettings(deadlyBossSrc)));
			Assert.AreEqual(Directory.GetFiles(targetUri.LocalPath).Length, 11);

			using (StreamReader sr = File.OpenText(Path.Combine(testDataPath, "DBMGUIResult.xml")))
			{
				string expectedXml = sr.ReadToEnd();
				Assert.AreEqual(expectedXml, project.Xml);
			}
		}

		[Test]
		public void TestDeadlyBossModsDBMHyjalBuild()
		{
			var deadlyBossSrc = new Uri(Path.Combine(deadlyBossUri.LocalPath, "DBM_Hyjal"));
			Project project = builder.Build(targetUri.LocalPath,
			                                importer.Import(new FolderImportSettings(deadlyBossSrc)));
			Assert.AreEqual(Directory.GetFiles(targetUri.LocalPath).Length, 12);

			using (StreamReader sr = File.OpenText(Path.Combine(testDataPath, "DBMHyjalResult.xml")))
			{
				string expectedXml = sr.ReadToEnd();
				Assert.AreEqual(expectedXml, project.Xml);
			}
		}

		[Test]
		public void TestDeadlyBossModsDBMKarazhanBuild()
		{
			var deadlyBossSrc = new Uri(Path.Combine(deadlyBossUri.LocalPath, "DBM_Karazhan"));
			Project project = builder.Build(targetUri.LocalPath,
			                                importer.Import(new FolderImportSettings(deadlyBossSrc)));
			Assert.AreEqual(Directory.GetFiles(targetUri.LocalPath).Length, 21);

			using (StreamReader sr = File.OpenText(Path.Combine(testDataPath, "DBMKarazhanResult.xml")))
			{
				string expectedXml = sr.ReadToEnd();
				Assert.AreEqual(expectedXml, project.Xml);
			}
		}

		[Test]
		public void TestDeadlyBossModsDBMOutlandsBuild()
		{
			var deadlyBossSrc = new Uri(Path.Combine(deadlyBossUri.LocalPath, "DBM_Outlands"));
			Project project = builder.Build(targetUri.LocalPath,
			                                importer.Import(new FolderImportSettings(deadlyBossSrc)));
			Assert.AreEqual(Directory.GetFiles(targetUri.LocalPath).Length, 13);

			using (StreamReader sr = File.OpenText(Path.Combine(testDataPath, "DBMOutlandsResult.xml")))
			{
				string expectedXml = sr.ReadToEnd();
				Assert.AreEqual(expectedXml, project.Xml);
			}
		}

		[Test]
		public void TestDeadlyBossModsDBMSerpentshrineBuild()
		{
			var deadlyBossSrc = new Uri(Path.Combine(deadlyBossUri.LocalPath, "DBM_Serpentshrine"));
			Project project = builder.Build(targetUri.LocalPath,
			                                importer.Import(new FolderImportSettings(deadlyBossSrc)));
			Assert.AreEqual(Directory.GetFiles(targetUri.LocalPath).Length, 21);

			using (StreamReader sr = File.OpenText(Path.Combine(testDataPath, "DBMSerpentshrineResult.xml")))
			{
				string expectedXml = sr.ReadToEnd();
				Assert.AreEqual(expectedXml, project.Xml);
			}
		}

		[Test]
		public void TestDeadlyBossModsDBMSunwellBuild()
		{
			var deadlyBossSrc = new Uri(Path.Combine(deadlyBossUri.LocalPath, "DBM_Sunwell"));
			Project project = builder.Build(targetUri.LocalPath,
			                                importer.Import(new FolderImportSettings(deadlyBossSrc)));
			Assert.AreEqual(Directory.GetFiles(targetUri.LocalPath).Length, 14);

			using (StreamReader sr = File.OpenText(Path.Combine(testDataPath, "DBMSunwellResult.xml")))
			{
				string expectedXml = sr.ReadToEnd();
				Assert.AreEqual(expectedXml, project.Xml);
			}
		}

		[Test]
		public void TestDeadlyBossModsDBMTheEyeBuild()
		{
			var deadlyBossSrc = new Uri(Path.Combine(deadlyBossUri.LocalPath, "DBM_TheEye"));
			Project project = builder.Build(targetUri.LocalPath,
			                                importer.Import(new FolderImportSettings(deadlyBossSrc)));
			Assert.AreEqual(Directory.GetFiles(targetUri.LocalPath).Length, 10);

			using (StreamReader sr = File.OpenText(Path.Combine(testDataPath, "DBMTheEyeResult.xml")))
			{
				string expectedXml = sr.ReadToEnd();
				Assert.AreEqual(expectedXml, project.Xml);
			}
		}

		[Test]
		public void TestDeadlyBossModsDBMZulAmanBuild()
		{
			var deadlyBossSrc = new Uri(Path.Combine(deadlyBossUri.LocalPath, "DBM_ZulAman"));
			Project project = builder.Build(targetUri.LocalPath,
			                                importer.Import(new FolderImportSettings(deadlyBossSrc)));
			Assert.AreEqual(Directory.GetFiles(targetUri.LocalPath).Length, 12);

			using (StreamReader sr = File.OpenText(Path.Combine(testDataPath, "DBMZulAmanResult.xml")))
			{
				string expectedXml = sr.ReadToEnd();
				Assert.AreEqual(expectedXml, project.Xml);
			}
		}

		[Test]
		public void TestInFlightAddonBuild()
		{
			Project project = builder.Build(targetUri.LocalPath,
			                                aceImporter.Import(new AceImportSettings(inFlightUri)));
			Assert.AreEqual(Directory.GetFiles(targetUri.LocalPath).Length, 7);

			using (StreamReader sr = File.OpenText(Path.Combine(testDataPath, "InFlightResult.xml")))
			{
				string expectedXml = sr.ReadToEnd();
				Assert.AreEqual(expectedXml, project.Xml);
			}
		}

		[Test]
		public void TestOutfitterBuild()
		{
			Project project = builder.Build(targetUri.LocalPath,
			                                importer.Import(new FolderImportSettings(outfitterUri)));
			Assert.AreEqual(Directory.GetFiles(targetUri.LocalPath).Length, 17);

			using (StreamReader sr = File.OpenText(Path.Combine(testDataPath, "OutfitterResult.xml")))
			{
				string expectedXml = sr.ReadToEnd();
				Assert.AreEqual(expectedXml, project.Xml);
			}
		}

		[Test]
		public void TestPlainAddonBuild()
		{
			Project project = builder.Build(targetUri.LocalPath,
			                                importer.Import(new FolderImportSettings(plainUri)));
			Assert.AreEqual(Directory.GetFiles(targetUri.LocalPath).Length, 4);

			using (StreamReader sr = File.OpenText(Path.Combine(testDataPath, "PlainResult.xml")))
			{
				string expectedXml = sr.ReadToEnd();
				Assert.AreEqual(expectedXml, project.Xml);
			}
		}

		[Test]
		public void TestRealisticAddonBuild()
		{
			Project project = builder.Build(targetUri.LocalPath,
			                                importer.Import(new FolderImportSettings(realisticUri)));
			Assert.AreEqual(Directory.GetFiles(targetUri.LocalPath).Length, 9);

			using (StreamReader sr = File.OpenText(Path.Combine(testDataPath, "RealisticResult.xml")))
			{
				string expectedXml = sr.ReadToEnd();
				Assert.AreEqual(expectedXml, project.Xml);
			}
		}

		[Test]
		public void TestRecursiveAddonBuild()
		{
			Project project = builder.Build(targetUri.LocalPath,
			                                importer.Import(new FolderImportSettings(recursiveUri)));
			Assert.AreEqual(Directory.GetFiles(targetUri.LocalPath).Length, 3);

			using (StreamReader sr = File.OpenText(Path.Combine(testDataPath, "RecursiveResult.xml")))
			{
				string expectedXml = sr.ReadToEnd();
				Assert.AreEqual(expectedXml, project.Xml);
			}
		}

		[Test]
		public void TestShamanWarningAddonBuild()
		{
			Project project = builder.Build(targetUri.LocalPath,
			                                aceImporter.Import(new AceImportSettings(shamanWarningUri)));
			Assert.AreEqual(Directory.GetFiles(targetUri.LocalPath).Length, 4);

			using (StreamReader sr = File.OpenText(Path.Combine(testDataPath, "ShamanWarningResult.xml")))
			{
				string expectedXml = sr.ReadToEnd();
				Assert.AreEqual(expectedXml, project.Xml);
			}
		}

		[Test]
		public void TestSWStatsBuild()
		{
			var swStatsSrc = new Uri(Path.Combine(swStatsUri.LocalPath, "SW_Stats"));
			Project project = builder.Build(targetUri.LocalPath,
			                                importer.Import(new FolderImportSettings(swStatsSrc)));
			Assert.AreEqual(Directory.GetFiles(targetUri.LocalPath).Length, 26);

			using (StreamReader sr = File.OpenText(Path.Combine(testDataPath, "SWStatsResult.xml")))
			{
				string expectedXml = sr.ReadToEnd();
				Assert.AreEqual(expectedXml, project.Xml);
			}
		}

		[Test]
		public void TestSWStatsProfilesBuild()
		{
			var swStatsSrc = new Uri(Path.Combine(swStatsUri.LocalPath, "SW_Stats_Profiles"));
			Project project = builder.Build(targetUri.LocalPath,
			                                importer.Import(new FolderImportSettings(swStatsSrc)));
			Assert.AreEqual(Directory.GetFiles(targetUri.LocalPath).Length, 4);

			using (StreamReader sr = File.OpenText(Path.Combine(testDataPath, "SWStatsProfilesResult.xml")))
			{
				string expectedXml = sr.ReadToEnd();
				Assert.AreEqual(expectedXml, project.Xml);
			}
		}

		[Test]
		public void TestSWUniLogBuild()
		{
			var swStatsSrc = new Uri(Path.Combine(swStatsUri.LocalPath, "SW_UniLog"));
			Project project = builder.Build(targetUri.LocalPath,
			                                importer.Import(new FolderImportSettings(swStatsSrc)));
			Assert.AreEqual(Directory.GetFiles(targetUri.LocalPath).Length, 6);

			using (StreamReader sr = File.OpenText(Path.Combine(testDataPath, "SWUniLogResult.xml")))
			{
				string expectedXml = sr.ReadToEnd();
				Assert.AreEqual(expectedXml, project.Xml);
			}
		}
	}
}